package org.jingouzhui.domain.strategy.service.rule.chain.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jingouzhui.domain.strategy.model.entity.StrategyEntity;
import org.jingouzhui.domain.strategy.repository.IStrategyRepository;
import org.jingouzhui.domain.strategy.service.armory.IStrategyDispatch;
import org.jingouzhui.domain.strategy.service.rule.chain.AbstractLogicChain;
import org.jingouzhui.domain.strategy.service.rule.chain.factory.DefaultLogicChainFactory;
import org.jingouzhui.types.common.Delimiter;
import org.jingouzhui.types.exception.AppException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description: 权重抽奖责任链
 * @author: jingouzhui
 * @date: 2025/4/29 13:12
 */
@Slf4j
@Component("rule_weight")
public class RuleWeightLogicChain extends AbstractLogicChain {

    /**
     * 用户已经消耗的积分，先固定，后续存入redis/mysql中
     */
    private final Long userScore = 0L;

    @Resource
    private IStrategyRepository strategyRepository;

    @Resource
    private IStrategyDispatch strategyDispatch;
    @Override
    protected String ruleModel() {
        return DefaultLogicChainFactory.LogicModel.RULE_WEIGHT.getCode();
    }

    @Override
    public DefaultLogicChainFactory.StrategyAwardVO logic(String userId, Long strategyId) {
        log.info("责任链-权重规则开始处理抽奖流程，userId：{}，strategyId：{}",userId,strategyId);
        StrategyEntity strategy = strategyRepository.queryStrategyByStrategyId(strategyId);
        //2.获取该策略对应的规则有哪些
        String ruleModels = strategy.getRuleModels();
        if (StringUtils.isEmpty(ruleModels)) {
            throw new AppException(strategyId+"对应的策略规则为空");
        }

        String ruleWeight = strategy.getRuleWeight();
        //3.如果没有权重查询的话，则直接交给下一个处理
        if (StringUtils.isEmpty(ruleWeight)) {
         return next().logic(userId,strategyId);
        }
        //4.查询规则值配置
        String ruleValue = strategyRepository.queryStrategyRuleValue(strategyId, ruleModel());
        Map<Long, String> analyticalValueMap = getAnalyticalValue(ruleValue);
        Long nextValue = analyticalValueMap
                        .keySet()
                        .stream()
                        .sorted(Comparator.reverseOrder())
                        .filter(key -> userScore >= key)
                        .findFirst()
                        .orElse(null);
        //5.开始抽奖
        if (nextValue != null) {
            log.info("责任链-权重规则接管抽奖流程，userId:{}，strategyId：{},rule_model:{}",userId,strategyId,ruleModel());
            Integer awardId = strategyDispatch.getRandomAwardId(strategyId, analyticalValueMap.get(nextValue));

            return DefaultLogicChainFactory.StrategyAwardVO.builder()
                    .awardId(awardId)
                    .logicModel(ruleModel())
                    .build();
        }

        //6.交给其他责任链处理
        log.info("责任链-权重规则放行抽奖流程，交给其他责任链处理，userId:{}，strategyId：{},rule_model:{}",userId,strategyId,ruleModel());
        return next().logic(userId,strategyId);
    }

    /**
     * 把rulevalue进行拆分 key:消耗的积分 value： key+awardList
     * @param ruleValue
     * @return
     */
    private  Map<Long, String> getAnalyticalValue(String ruleValue){
        Map<Long, String> scoreAwardMap = new ConcurrentHashMap<>();
        String[] ruleKeyValueList = ruleValue.split(Delimiter.SPACE);
        for (String ruleValueKey : ruleKeyValueList) {
            if (StringUtils.isBlank(ruleValueKey)) {
                return scoreAwardMap;
            }
            //分割字符串获取key&value
            String[] split = ruleValueKey.split(Delimiter.COLON);
            if (split.length != 2) {
                throw new IllegalArgumentException("rule_weight rule_rule invalid input format" + ruleValueKey);
            }
            scoreAwardMap.put(Long.parseLong(split[0]), ruleValueKey);
        }
        return scoreAwardMap;
    }
}
